﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Text.RegularExpressions;

namespace LookAHead
{
    class FileRW
    /* handels read and write to files*/
    {
        public static void ReadAndRunBoardWithMbh(String FileNamePDB)
        {
            StreamReader re = File.OpenText(FileNamePDB);
            string input = null;
            char[] del = { ',' };
            String[] elements;
            input = re.ReadLine();
            int x, y, counter = 0;
            while (!input.Equals("END"))
            {
                elements = input.Split(del);
                x = int.Parse(elements[0]);
                y = int.Parse(elements[1]);
                program.GridBoard.GridMBH[counter] = new MemBasedH(x, y);
                for (int i = 0; i < program.GridBoard.MaxX; i++)
                    for (int j = 0; j < program.GridBoard.MaxY; j++)
                    {
                        input = re.ReadLine();
                        program.GridBoard.GridMBH[counter].AddH(i, j, double.Parse(input));
                    }
                counter++;
                input = re.ReadLine();
            }
        }
        /*************************************************/
        public static void ReadBoard(String FileNameIn)
        //read the board from the file "FileNameIn"
        {
            program.GridBoard = null;
            program.Init();
            StreamReader re = File.OpenText(FileNameIn);
            string c, input = null;
            char[] del = { ' ' };
            String[] elements;
            int size_x, size_y, x_goal, y_goal, x_start, y_start;
            double obstacle_counter = 0;
            input = re.ReadLine();
            input = re.ReadLine();
            elements = input.Split(del);
            size_x = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            elements = input.Split(del);
            size_y = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            elements = input.Split(del);
            x_goal = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            elements = input.Split(del);
            y_goal = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            elements = input.Split(del);
            x_start = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            elements = input.Split(del);
            y_start = (short)int.Parse(elements[1]);
            input = re.ReadLine();
            program.GridBoard = new Grid(size_x, size_y, x_goal, y_goal, x_start, y_start);
            for (int index_x = 0; index_x < size_x; index_x++)
            {
                input = re.ReadLine();
                for (int index_y = 0; index_y < size_y; index_y++)
                {
                    c = input.Substring(index_y, 1);
                    if (c == "@")
                    {
                        program.GridBoard.Get(index_x, index_y).CreateObstacle();
                        obstacle_counter++;
                    }
                }
            }
            program.GridBoard.ObstaclePresentge = obstacle_counter / (size_x * size_y);
        }
        /********************************************************************************/
        public static void ReadAndRunBoard(String FileNameIn, String FileNameOut)
        /* read the board from the file "FileNameIn"
         * run all the algoritem with function  "Run_Algo(FileNameOut)" 
         * and save the ouput to file FileNameOut*/
        {
            ReadBoard(FileNameIn);
            program.RunAlgo("", FileNameOut);
        }
        /********************************************************************************/
        public static void ReadAndRunBoard(String FileNameIn, String FileMbh, String FileNameOut)
        /* read the board from the file "FileNameIn"
         * run all the algoritem with function  "Run_Algo(FileNameOut)" 
         * run some of the algorithem that use pathmax & bpmx using the mbh file
         * and save the ouput to file FileNameOut*/
        {
            ReadBoard(FileNameIn);
            program.RunAlgo(FileMbh, FileNameOut);
        }
        /********************************************************************************/
        public static void CreateMbhFile(String FileNameIn, String FileNameOut)
        /*read grid from FileNameIn and create pdb save it to file FileNameOut*/
        {
            ReadBoard(FileNameIn);
            program.GridBoard.CreateMBH();
            FileStream stream = new FileStream(FileNameOut, FileMode.Create);
            StreamWriter writer = new StreamWriter(stream);
            for (int i = 0; i < program.GridBoard.GridMBH.Length; i++)
            {
                writer.WriteLine(program.GridBoard.GridMBH[i].CenterCity.x + "," + program.GridBoard.GridMBH[i].CenterCity.y);
                for (int x = 0; x < program.GridBoard.MaxX; x++)
                {
                    for (int y = 0; y < program.GridBoard.MaxY; y++)
                        writer.WriteLine(program.GridBoard.GridMBH[i].PdbCost[x, y]);
                }
            }
            writer.Write("END");
            writer.Close();
            stream.Close();
        }
        /********************************************************************************/
        public static void PrintFinalDetails(String file)
        //function printing final data to file
        {
            FileStream stream = new FileStream(file, FileMode.Create);
            StreamWriter writer = new StreamWriter(stream);
            writer.Write("A*" + ",");
            PrintDetails(program.AstarNum, 0, writer, file);
            writer.Write("IDA*" + ",");
            PrintDetails(program.IdaStarNum, 0, writer, file);
            //bpmx
            writer.Write("BpmxA*" + ",");
            PrintDetails(program.AstarNum, 1, writer, file);
            writer.Write("BpmxIDA*" + ",");
            PrintDetails(program.IdaStarNum, 1, writer, file);
            //endbpmx
            for (int k = 0; k < program.Num_Lookahead; k++)
            {
                writer.Write("LkA*" + k + ",");
                PrintDetails(program.LookAHeadNum, k, writer, file);
                writer.Write("Mrec" + k + ",");
                PrintDetails(program.MrecNum, k, writer, file);
                //bpmx
                writer.Write("BpmxLkA*" + k + ",");
                PrintDetails(program.LookAHeadWithBpmxNum, k, writer, file);
                writer.Write("BpmxMrec" + k + ",");
                PrintDetails(program.MrecWithBpmxNum, k, writer, file);
                //endbpmx
            }
            writer.Write("LDFS" + ",");
            PrintDetails(3, 0, writer, file);
            writer.Write("BFS" + ",");
            PrintDetails(4, 0, writer, file);
            writer.Write("UCS" + ",");
            PrintDetails(5, 0, writer, file);

            writer.Close();
            stream.Close();
        }
        /********************************************************************************/
        public static void PrintDetails(int i, int j, StreamWriter writer, String File)
        //function print featiles for algoritem to the output file
        {
            writer.Write(program.GridBoard.MaxX + "*" + program.GridBoard.MaxY + ",");
            writer.Write(program.GridBoard.ObstaclePresentge * 100 + ",");
            writer.Write(program.TotalMem[i, j] + ",");
            writer.Write(program.TotalExpnded[i, j] + ",");
            writer.Write(program.TotalReExpnded[i, j] + ",");
            writer.Write(program.TotalGenrated[i, j] + ",");
            writer.Write(program.TotalReGenrated[i, j] + ",");
            writer.Write(program.TotalSolCost[i, j] + ",");
            writer.Write((program.TotalSolDepth[i, j]) + ",");
            writer.Write(program.TotalLookaHeadVisited[i, j] + ",");
            writer.Write(program.Stopwatch[i, j].Elapsed.TotalMilliseconds + ",");
            writer.Write(program.Sol[i, j] + ",");
            writer.Write(program.TotalnumIt[i, j] + ",");
            writer.Write(program.TotalMaxStackSize[i, j] + ",");
            writer.WriteLine(File);
            program.Stopwatch[i, j] = new Stopwatch();
        }
        /********************************************************************************/
        public static void AttachFilesRooms(string Type)
        /* takes all the outputfile and atcche to one file named all.txt*/
        {
            int[] arraySize = { 0, 1, 2, 3, 4 };
            string input = null;
            String FileNameOut = "output/all.txt";
            FileStream stream = new FileStream(FileNameOut, FileMode.Create);
            StreamWriter writer = new StreamWriter(stream);
            for (int i = 0; i < arraySize.Length; i++)
            {
                for (int y = 1; y < 11; y++)
                {
                    String FileNameIn = "rooms/output/" + arraySize[i] + "/" + Type + "/" + i + "_" + y + ".txt";
                    if (File.Exists(FileNameIn))
                    {
                        StreamReader re = File.OpenText(FileNameIn);
                        while ((input = re.ReadLine()) != null)
                            writer.WriteLine(input);
                    }
                }
            }
            writer.Close();
            stream.Close();
        }
        /********************************************************************************/
        public static void AttachFiles()
        /* takes all the outputfile and atcche to one file named all.txt*/
        {
            int[] arraySize = { 10, 100, 500, 1000 };
            int[] arrayObsitcle = { 0, 25, 50, 75 };
            string input = null;
            String FileNameOut = "output/all.txt";
            FileStream stream = new FileStream(FileNameOut, FileMode.Create);
            StreamWriter writer = new StreamWriter(stream);
            for (int i = 0; i < arraySize.Length; i++)
            {
                for (int j = 0; j < arrayObsitcle.Length; j++)
                    for (int y = 0; y < 100; y++)
                    {
                        String FileNameIn = "output/" + arraySize[i] + "/" + arrayObsitcle[j] + "/" + y + ".txt";
                        if (File.Exists(FileNameIn))
                        {
                            StreamReader re = File.OpenText(FileNameIn);
                            while ((input = re.ReadLine()) != null)
                                writer.WriteLine(input);
                        }
                    }
            }
            writer.Close();
            stream.Close();
        }
    }
}
